package edu.fourtwelve.Data;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Christopher C. Hunt
 */
public class DatabaseSingleton implements DBConstants {

    private static final Logger log = Logger.getLogger(DatabaseSingleton.class.getName());

    private Connection cn;
    private DatabaseSingleton() {
        try {
            // Load in the driver
            Class.forName(DRIVER_NAME);
            log.config("...Driver loaded");
            // Establish a connection
            cn = DriverManager.getConnection(PROTOCOL + DB_NAME);
            log.log(Level.CONFIG, "Connection = {0}", new Object[] {cn.toString()});
        } catch (ClassNotFoundException ex) {
            log.log(Level.SEVERE, "Failure creating the DB", ex);
        } catch (SQLException ex) {
            log.log(Level.SEVERE, "Failure creating the DB", ex);
        }
    }

    public static DatabaseSingleton getInstance() {
        if (DatabaseSingletonHolder.INSTANCE == null) {
            throw new NullPointerException();
        }
        return DatabaseSingletonHolder.INSTANCE;
    }

    public Connection getConnection() {
        if(DatabaseSingletonHolder.INSTANCE != null && DatabaseSingletonHolder.INSTANCE.cn != null) {
            return DatabaseSingletonHolder.INSTANCE.cn;
        } else {
            throw new NullPointerException();
        }
    }
    
    public void close() throws SQLException {
        if(!DatabaseSingletonHolder.INSTANCE.cn.isClosed()) {
            DatabaseSingletonHolder.INSTANCE.cn.close();
            DatabaseSingletonHolder.INSTANCE.cn = null;
        }
    }
    
    public void reopenConnection() throws SQLException {
        if(isConnClosed()) {
            cn = DriverManager.getConnection(PROTOCOL + DB_NAME);
        }
    }
    
    public boolean isConnClosed() {
        boolean retVal = true;
        try {
            retVal = ((DatabaseSingletonHolder.INSTANCE == null) || (DatabaseSingletonHolder.INSTANCE.cn == null)
                    || (DatabaseSingletonHolder.INSTANCE.cn.isClosed()));
        } catch (SQLException ex) {
           log.log(Level.SEVERE, null, ex);
        }
        return retVal;
    }
    private static class DatabaseSingletonHolder {

        private static final DatabaseSingleton INSTANCE = new DatabaseSingleton();
    }
}
